<?php
namespace modules\game\services\method;

class ThreePByOne extends IMethod{
		
	public static $_name = __CLASS__;

	//检测牌
	public function test(Array $testPoker){
		$this->_testNum = count($testPoker);
		$this->_testPoker = $testPoker;
		if($this->_testNum % 4) return false;
		$poker = [];
		for($i = 0; $i < $this->_testNum ; ++$i){
			$key = floor($this->_testPoker[$i] / 10);
			if(isset($poker[$key])){
				$poker[$key][] = $this->_testPoker[$i];
			}else{
				$poker[$key] = [$this->_testPoker[$i]];
			}
		}
		$single = $three = $other = 0;
		$threePoker = [];
		foreach( $poker as $val){
			if(count($val) === 1){
				++$single;
				continue;
			}
			if(count($val) === 3){
				++$three;
				$threePoker = array_merge($threePoker, $val);
				continue;
			}
			++$other;
		}
		//三张必须为连顺
		if($three === 1){
			$testRet = self::getInstance(ThreeP::$_name)->test($threePoker);
		}else{
			$testRet = self::getInstance(ThreePStraight::$_name)->test($threePoker);
		}
		
		return ($other || $single !== $three || !$testRet) ? false : true;
	}
	/**
	 * 牌分段，顺子归块
	 * exp: [3,4,5,6,7,9,10,11,12,13,16]
	 * return [
	 * 		[3,4,5,6,7],
	 * 		[9,10,11,12,13],
	 * 		[16]
	 * ];
	 */
	public function straightSplit(Array $pokerNum){
		$flag = 0;
		$data = $chunk = [];
		foreach($pokerNum as $one){
			if(($flag + 1) === $one){
				$chunk[] = $one;
			}else{
				if($chunk){
					$data[] = $chunk;
				}
				$chunk = [$one];
			}
			$flag = $one;
		}
		return $data;
	}
	/**
	 * 出牌策略
	 * @param  array $userPoker 用户当前的牌,已模块
	 * @return array 出的牌 | bool 没有此类型的牌，不出
	 */
	public function out($userPoker){//出牌
		//先选出顺子
		$straight = self::getInstance(ThreePStraight::$_name)->out($userPoker);
		if($straight){
			$valid = array_filter($userPoker,function($a){
				return count($a) === 1;
			});
			if(count($valid) >= ($len = count($straight) / 3)){
				$n = 0;
				foreach($valid as $one){
					if(++$n && $n > $len){
						break;
					}
					$straight = array_merge($straight,$one);
				}
				sort($straight);
				if($this->test($straight)){
					return $straight;
				}
			}
		}
		return false;
		
	}
	/**
	 * 压牌策略
	 * @param  array $userPoker     我目前的牌
	 * @param  array $opponentPoker 当前需要被压的牌
	 * @param  bool  $intense  是否尽力压牌  true是  or false 否
	 * @return array  出牌 | bool: false 压不住
	 */
	public function suppress($userPoker,$opponentPoker,$intense){
		$oppoStraight = array_filter($opponentPoker,function($a){
			return count($a) === 3;
		});
		//先选出顺  三带一
		if(count($oppoStraight) === 1){
			$userStraight = self::getInstance(ThreeP::$_name)->suppress($userPoker,$oppoStraight,false);
		}else{     //多顺带一
			$userStraight = self::getInstance(ThreePStraight::$_name)->suppress($userPoker,$oppoStraight,false);
		}
		if($userStraight){
			$valid = array_filter($userPoker,function($a){
				return count($a) === 1;
			});
			if(count($valid) >= ($len = count($userStraight) / 3)){
				$n = 0;
				foreach($valid as $one){
					if(++$n && $n > $len){
						break;
					}
					$userStraight = array_merge($userStraight,$one);
				}
				sort($userStraight);
				if($this->test($userStraight)){
					return $userStraight;
				}
				
			}
		}
		if($intense){//强制拆牌出牌
			return $this->forceSuppress($userPoker,$opponentPoker);
		}
		return false;
	}
}